#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Модуль разбора страницы Сценария игры на составляющие сценария: уровни, задания, подсказки, бонусы, ответы, комментарии
#

import re, EnLib
from BeautifulSoup import BeautifulSoup
from Scenario import Scenario
from DbShell import Db
import os.path

def parseAndSaveScenario(domain, gameId):
    scenario = Scenario(gameId)
    
    filePath = EnLib.getScenarioPath(domain, gameId)
    if not os.path.exists(filePath):
        print 'Scenario file for %d in %s not exists' % (gameId,domain,)
        return
    
    file = open(filePath, 'r')
    fullText = file.read()
    file.close()
    file = None
    soup = BeautifulSoup(fullText)
    soup.prettify()
    body = soup.body
    table = body.findAll('table',{'width':'100%', 'cellspacing':'0', 'cellpadding':'0', 'border':'0'})  # Выбираем только таблицы с такой сигнатурой (т.к. в задании могут встречатся внутренние таблицы)
    # Прочистим список таблиц, т.к. могут сюда затесаться таблицы из заданий:
    cleaner = []
    for i in range(1,len(table)):
        tb = table[i]
        if len(tb.attrs) > 4:   # Если у таблицы более 4 атрибутов, значит она "ЛЕВАЯ" (не принадлежит таблицам разметки уровней)
            cleaner.append(i)   # хоп, поймали левую таблицу в выдаче
        else:
            try:
                levelCaption = str(tb.tr.td.div.div.contents[1]).strip() # Если получить название не удалось - значит это не разметочная таблица уровня
                #print '**** ', levelCaption, ' *******'  
            except AttributeError,e:
                #print 'ERRROR:'
                #print tb
                #print ''
                #print e
                cleaner.append(i)   # хоп, поймали левую таблицу в выдаче
                
    
    shift = 0
    if len(cleaner) > 0:
        for idx in cleaner:
            del table[idx-shift]
            shift = shift + 1
    cleaner = None
    # Вот теперь в списке table нет "левых" таблиц :)
    # 0-линки на уровни, 1...end - уровни (!)
    
    for levelNumber in range(1, len(table)):
        #print levelNumber
        level = table[levelNumber] # Взяли таблицу, содержащую уровень целиком
        #print ' '
        #print level
        #print ' '
        levelCaption = str(level.tr.td.div.div.contents[1]).strip() # Человечное название уровня
        
        scenario.addLevelCaption(levelNumber, levelCaption)
        
        scenarioBlock = level.tr.td.div.div.nextSibling.nextSibling # <div class="scenarioBlock">
        
        helperSoup = scenarioBlock.findAll(id=re.compile('LevelsScenarioRepeater_.+LevelHelp'))
        helpers = []
        for el in helperSoup:
            if len(el.contents) == 0:
                helpers.append('')  # hack на случай если текст подсказки пустой (такое есть в игре 1953, vladivostok)
            elif len(el.contents) == 1:
                helpers.append(el.contents[0])
            else:
                helpers.append(el)

        
        for i in range(0,len(helpers),2):
            res = re.findall(r'№(\d+)', helpers[i].__str__(), re.DOTALL) # Выделим из заголовка подсказки её номер (русскоязыный вариант)
            if len(res) == 0:
                res = re.findall(r'#(\d+)', helpers[i].__str__(), re.DOTALL) # Выделим из заголовка подсказки её номер (не русскоязычный вариант)
                if len(res) == 0:
                    helperNumber = 0    # ПЛОХО! значит заголовок подсказки не распарсился!
                else:
                    helperNumber = res[0]
            else:
                helperNumber = res[0]
            scenario.addLevelHelper(levelNumber, helperNumber, helpers[i], helpers[i+1])
        
        taskSoup = scenarioBlock.findAll(id=re.compile('LevelTasksRepeater'))
        taskPieces = len(taskSoup)
        for i in range(0, taskPieces, 2):
            if taskPieces > (i+1):
                scenario.addLevelTask(levelNumber, taskSoup[i+1], taskSoup[i].contents[0])
        
        commentSoup = scenarioBlock.findAll(id=re.compile('lblLevelComment'))
        for i in range(0,len(commentSoup),2):
            commentLines = [line.__str__() for line in commentSoup[i+1].contents]
            comment = '\r\n'.join(commentLines)
            scenario.addLevelComment(levelNumber,comment)  # Список заданий уровня в виде списка словарей //'title':commentSoup[i].contents[0]
        #bonuses = []
        #bonusSoup = scenarioBlock.findAll(id=re.compile('LevelBonusesRepeater'))
        #print bonusSoup
        #for i in range(0,len(bonusSoup),2):
        #    print i
            #bonuses.append({'title':bonusSoup[i].contents[0],'comment':commentSoup[i+1]})  # Список заданий уровня в виде списка словарей
        #print bonuses
        #levelAnswers = scenarioBlock.contents[5]
    
    scenario.save()
    # Освободим память принудительно
    helperNumber = None
    helpers = None
    helperSoup = None
    taskSoup = None
    comment = None
    commentLines = None
    commentSoup = None
    #  Освободим память принудительно
    soup.decompose()
    body.decompose()
    body = None
    fullText = None
    level = None
    levelCaption = None
    levelNumber = None
    res = None
    scenarioBlock = None
    scenario = None
    table = None
    soup = None

#---------------------------------------------------------------------

#parseAndSaveScenario('world.en.cx', 1246)
#exit()

db = Db()
q = 'SELECT game_id, game_domain FROM enlab_games WHERE (has_scenario=1 AND `scenario_parsed`=0)'
r = db.query(q)
games = db.fetchall()
db = None
gamesCount = len(games)
print 'games count:', gamesCount
i = 1
for game in games:
    (gameId, domain) = game
    print gameId, domain,'(' , i , 'of', gamesCount, ')', 
    parseAndSaveScenario(domain, gameId)
    print '... done'
    i += 1

